package com.seeyon.apps.thirdapp.util;

import com.alibaba.fastjson.JSONObject;
import com.seeyon.ctp.util.json.JSONUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

//import net.sf.json.JSONObject;


@SuppressWarnings("deprecation")
public  class HttpRequestUtil {

    private static final Log log = LogFactory.getLog(HttpRequestUtil.class);
    
    public static JSONObject sendPost(String url, String content) {
    	return sendPost(url,content,"json");
    	
    }

    public static JSONObject sendPost(String url, String content, String contentType) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = getDefaultHttpClient();
            int CONNECTION_TIMEOUT = 10 * 1000;
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_TIMEOUT).setConnectTimeout(CONNECTION_TIMEOUT).setSocketTimeout(CONNECTION_TIMEOUT).build();
            httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            if("json".equals(contentType))
            {
            	httpPost.addHeader("Content-Type", "application/json");
            	httpPost.addHeader("Accept", "application/json");
            }
            else
            {
            	httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
            }
            StringEntity requestEntity = new StringEntity(content, "UTF-8");
            httpPost.setEntity(requestEntity);
            httpResponse = httpClient.execute(httpPost, new BasicHttpContext());
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null) {
                String resultStr = EntityUtils.toString(entity, "UTF-8");
                JSONObject result = null;
                try{
                	result = JSONUtil.parseJSONString(resultStr, JSONObject.class);
                }catch(Exception e)
                {
                	result=new JSONObject();
                	result.put("msg",resultStr);
                }
                return result;
            }
        } catch(Exception e) {
            log.error("", e);
        } finally {
            if(httpResponse != null) {
                try {
                    httpResponse.close();
                } catch(Exception e) {
                }
            }
            if(httpPost != null) {
                try {
                    httpPost.releaseConnection();
                } catch(Exception e) {
                }
            }
            if(httpClient != null) {
                try {
                    httpClient.close();
                } catch(Exception e) {
                }
            }
        }
        return null;
    }

    public static DefaultHttpClient getDefaultHttpClient() throws Exception
	{
    	DefaultHttpClient httpClient = new DefaultHttpClient();
	    SSLContext ssl_ctx = SSLContext.getInstance("TLS");
	    X509TrustManager x509TrustManager =   new X509TrustManager() {
	        public X509Certificate[] getAcceptedIssuers() {
	            return null;
	        }

	        public void checkClientTrusted(X509Certificate[] certs, String t) {
	        }

	        public void checkServerTrusted(X509Certificate[] certs, String t) {
	        }
	    };
	    javax.net.ssl.TrustManager[] certs = new javax.net.ssl.TrustManager[] { x509TrustManager };
	    ssl_ctx.init(null, certs, new SecureRandom());
	    org.apache.http.conn.ssl.SSLSocketFactory ssf = new org.apache.http.conn.ssl.SSLSocketFactory(ssl_ctx, org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
	    ClientConnectionManager ccm = httpClient.getConnectionManager();
	    SchemeRegistry sr = ccm.getSchemeRegistry();
	    sr.register(new org.apache.http.conn.scheme.Scheme("https", 443, ssf));
	    return new DefaultHttpClient(ccm, httpClient.getParams());
	}
    
    
    public static JSONObject sendGet(String url) {
    	CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HttpClients.createDefault();
            int CONNECTION_TIMEOUT = 10 * 1000;
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_TIMEOUT).setConnectTimeout(CONNECTION_TIMEOUT).setSocketTimeout(CONNECTION_TIMEOUT).build();
            httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-Type", "application/json");
            httpGet.addHeader("Accept", "application/json");
            httpResponse = httpClient.execute(httpGet, new BasicHttpContext());
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null) {
                String resultStr = EntityUtils.toString(entity, "UTF-8");
                JSONObject result = JSONUtil.parseJSONString(resultStr, JSONObject.class);
                return result;
            }
        } catch(Exception e) {
            log.error("", e);
        } finally {
            if(httpResponse != null) {
                try {
                    httpResponse.close();
                } catch(Exception e) {
                }
            }
            if(httpGet != null) {
                try {
                    httpGet.releaseConnection();
                } catch(Exception e) {
                }
            }
            if(httpClient != null) {
                try {
                    httpClient.close();
                } catch(Exception e) {
                }
            }
        }
        return null;
    }
    public static JSONObject sendGetUser(String url, String token) {
    	CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HttpClients.createDefault();
            int CONNECTION_TIMEOUT = 10 * 1000;
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_TIMEOUT).setConnectTimeout(CONNECTION_TIMEOUT).setSocketTimeout(CONNECTION_TIMEOUT).build();
            httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-Type", "application/json");
            httpGet.addHeader("Accept", "application/json");
            httpGet.addHeader("Authorization", "Bearer "+token);
            httpResponse = httpClient.execute(httpGet, new BasicHttpContext());
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null) {
                String resultStr = EntityUtils.toString(entity, "UTF-8");
                JSONObject result = JSONUtil.parseJSONString(resultStr, JSONObject.class);
                return result;
            }
        } catch(Exception e) {
            log.error("", e);
        } finally {
            if(httpResponse != null) {
                try {
                    httpResponse.close();
                } catch(Exception e) {
                }
            }
            if(httpGet != null) {
                try {
                    httpGet.releaseConnection();
                } catch(Exception e) {
                }
            }
            if(httpClient != null) {
                try {
                    httpClient.close();
                } catch(Exception e) {
                }
            }
        }
        return null;
    }
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        HttpsURLConnection httpUrlConn = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(requestUrl);
            httpUrlConn = (HttpsURLConnection) url.openConnection();
            if (requestUrl.startsWith("https://oapi.dingtalk.com")) {
                httpUrlConn.setRequestProperty("Content-Type", "application/json");
            }

            TrustManager[] tm = { new TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.getServerSessionContext().setSessionCacheSize(1000);
            sslContext.init(null, tm, new SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            httpUrlConn.setRequestMethod(requestMethod);
            httpUrlConn.setConnectTimeout(20000);
            httpUrlConn.setReadTimeout(20000);
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpUrlConn.connect();
            }

            if (outputStr != null) {
                outputStream = httpUrlConn.getOutputStream();
                outputStream.write(outputStr.getBytes("UTF-8"));
            }

            inputStream = httpUrlConn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

                jsonObject =  JSONUtil.parseJSONString(buffer.toString(), JSONObject.class);
        } catch (Exception e) {
            log.error("�Ϳ�,��HTTPS�������쳣��" + requestUrl, e);
            if (e.getMessage().contains("401 for URL")) {
                return JSONUtil.parseJSONString("{id:\"401\"}", JSONObject.class);
            }
            return null;
        } finally {
            closeConnection(httpUrlConn, outputStream, inputStream, inputStreamReader, bufferedReader);
        }
        return jsonObject;
    }
    
    /**
     * ������֤ https ����
     * @param requestUrl
     * @param requestMethod
     * @param outputStr
     * @return
     */
    public static String httpsSsoRequest(String requestUrl, String requestMethod, String outputStr) {
    	log.info("���뵽soohttps ����");
        HttpsURLConnection httpUrlConn = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(requestUrl);
            httpUrlConn = (HttpsURLConnection) url.openConnection();
            if (requestUrl.startsWith("https://oapi.dingtalk.com")) {
                httpUrlConn.setRequestProperty("Content-Type", "application/json");
            }

            TrustManager[] tm = { new TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.getServerSessionContext().setSessionCacheSize(1000);
            sslContext.init(null, tm, new SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            httpUrlConn.setRequestMethod(requestMethod);
            httpUrlConn.setConnectTimeout(20000);
            httpUrlConn.setReadTimeout(20000);
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpUrlConn.connect();
            }

            int code = httpUrlConn.getResponseCode();
        	log.info("�����code:" + code );
        	if (200 == code) {
				return "0";
			}
        } catch (Exception e) {
        	log.info("���������쳣��" + requestUrl, e);
            log.error("���������쳣��" + requestUrl, e);
            if (e.getMessage().contains("401 for URL")) {
                return "1";
            }
            return "1";
        } finally {
            closeConnection(httpUrlConn, outputStream, inputStream, inputStreamReader, bufferedReader);
        }
        return "1";
    }
    
    /**
     * ������֤ https ����
     * @param requestUrl
     * @param requestMethod
     * @param outputStr
     * @return
     */
    public static String httpSsoRequest(String requestUrl, String requestMethod, String outputStr) {
    	
        HttpURLConnection httpUrlConn = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(requestUrl);
            httpUrlConn = (HttpURLConnection) url.openConnection();
            if (requestUrl.startsWith("https://oapi.dingtalk.com")) {
                httpUrlConn.setRequestProperty("Content-Type", "application/json");
            }

            TrustManager[] tm = { new TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.getServerSessionContext().setSessionCacheSize(1000);
            sslContext.init(null, tm, new SecureRandom());
            
            /*SSLSocketFactory ssf = sslContext.getSocketFactory();

            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
*/
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            httpUrlConn.setRequestMethod(requestMethod);
            httpUrlConn.setConnectTimeout(20000);
            httpUrlConn.setReadTimeout(20000);
            log.info("���뵽soohttps ��������ǰ");
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpUrlConn.connect();
            }

            log.info("���뵽soohttps �������Ӻ�");
            int code = httpUrlConn.getResponseCode();
        	log.info("�����code:" + code );
        	if (200 == code) {
				return "0";
			}
        } catch (Exception e) {
        	log.info("���������쳣��" + requestUrl, e);
            log.error("���������쳣��" + requestUrl, e);
            if (e.getMessage().contains("401 for URL")) {
                return "1";
            }
            return "1";
        } finally {
            closeConnection(httpUrlConn, outputStream, inputStream, inputStreamReader, bufferedReader);
        }
        return "1";
    }
    
    
    /**
     * ����http����
     * @param url
     * @return
     */
    public static boolean sendSsoGet(String url) {
    	CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HttpClients.createDefault();
            int CONNECTION_TIMEOUT = 10 * 1000;
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_TIMEOUT).setConnectTimeout(CONNECTION_TIMEOUT).setSocketTimeout(CONNECTION_TIMEOUT).build();
            httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-Type", "application/json");
            httpGet.addHeader("Accept", "application/json");
            httpResponse = httpClient.execute(httpGet, new BasicHttpContext());
           int code = httpResponse.getStatusLine().getStatusCode();
           if (200 == code) {
        	   return true;
           }
        } catch(Exception e) {
            log.error("", e);
        } finally {
            if(httpResponse != null) {
                try {
                    httpResponse.close();
                } catch(Exception e) {
                }
            }
            if(httpGet != null) {
                try {
                    httpGet.releaseConnection();
                } catch(Exception e) {
                }
            }
            if(httpClient != null) {
                try {
                    httpClient.close();
                } catch(Exception e) {
                }
            }
        }
        return false;
    }
    
    
    private static void closeConnection(HttpURLConnection httpUrlConn, OutputStream outputStream, InputStream inputStream, InputStreamReader inputStreamReader, BufferedReader bufferedReader) {
        if (outputStream != null) {
            try {
                outputStream.close();
                outputStream = null;
            } catch (IOException e2) {
            }
        }
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
                bufferedReader = null;
            } catch (IOException e1) {
            }
        }
        if (inputStreamReader != null) {
            try {
                inputStreamReader.close();
                inputStreamReader = null;
            } catch (IOException e1) {
            }
        }
        if (inputStream != null) {
            try {
                inputStream.close();
                inputStream = null;
            } catch (IOException e) {
            }
        }
        if (httpUrlConn != null) {
            httpUrlConn.disconnect();
            httpUrlConn = null;
        }
    }
    
    
    public static JSONObject httpGet(String url) {
    	RestTemplate restTemplate = null;
        try {
            restTemplate = getRestTemplate(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        assert restTemplate != null;
        return restTemplate.getForObject(url, JSONObject.class);
    }
    
    /**
     * restTemplate https ��֤�Զ���
     *
     * @return RestTemplate
     * @throws Exception
     */
    private static RestTemplate getRestTemplate(String url) throws Exception {
    	if(url.toLowerCase().startsWith("https"))
    	{
	        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
	        SSLContext sslContext = SSLContexts.custom()
	                .loadTrustMaterial(null, acceptingTrustStrategy)
	                .build();
	        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
	        CloseableHttpClient httpClient = HttpClients.custom()
	                .setSSLSocketFactory(csf)
	                .build();
	
	        HttpComponentsClientHttpRequestFactory requestFactory =
	                new HttpComponentsClientHttpRequestFactory();
	        requestFactory.setHttpClient(httpClient);
	        return new RestTemplate(requestFactory);
    	}
    	else
    	{
    		SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setReadTimeout(15000);
            factory.setConnectTimeout(15000);
            return new RestTemplate(factory);
    	}
    }
    
    
    
}
